<template>
  <div class="home">
    <div id="map" v-loading="loading"></div>
    <!-- 飞行数据 -->
    <div class="flight-msg">
      <div class="flight-history">
        <div class="flight-history-title">
          <img v-if="mapIndex === 1" src="@/assets/img/home/flight_history_dark.png" alt="" />
          <img v-if="mapIndex === 2" src="@/assets/img/home/flight_history.png" alt="" />
          <p>历史飞行</p>
        </div>
        <div
          class="flight-history-msg"
          :class="{
            'flight-history-msg-dark': mapIndex === 1,
          }"
        >
          <p>{{ historyFlightNum }}</p>
        </div>
      </div>
      <div class="flight-online" @click="openMultiScreen">
        <div class="flight-online-title">
          <img v-if="mapIndex === 1" src="@/assets/img/home/flight_online_dark.png" alt="" />
          <img v-if="mapIndex === 2" src="@/assets/img/home/flight_online.png" alt="" />
          <p>在线飞行</p>
        </div>
        <div
          class="flight-online-msg"
          :class="{
            'flight-online-msg-dark': mapIndex === 1,
          }"
        >
          <p>{{ onlineFlightNum }}</p>
        </div>
      </div>
    </div>
    <!-- 切换底图 -->
    <div class="base-map">
      <img src="@/assets/img/home/icon_switch_dark.png" alt="" @click="openSwitchMap" />
      <div class="switch-map" v-show="switchMapShow">
        <div class="switch-map-con" @click="switchMap(1)" style="margin-right: 10px">
          <img v-show="mapIndex === 1" src="@/assets/img/home/icon_skymap_active.png" alt="" />
          <img v-show="mapIndex === 2" src="@/assets/img/home/icon_skymap.png" alt="" />
          <p :class="mapIndex === 1 ? 'map-active' : ''">天地图</p>
        </div>
        <div class="switch-map-con" @click="switchMap(2)">
          <img v-show="mapIndex === 2" src="@/assets/img/home/icon_map_active.png" alt="" />
          <img v-show="mapIndex === 1" src="@/assets/img/home/icon_map.png" alt="" />
          <p :class="mapIndex === 2 ? 'map-active' : ''">电子地图</p>
        </div>
      </div>
    </div>
    <!-- 条件筛选 -->
    <div class="search-box">
      <div class="search-time">
        <el-date-picker
          v-model="date"
          type="daterange"
          popper-class="drop-down-date"
          range-separator="至"
          start-placeholder="开始时间"
          end-placeholder="结束时间"
          @change="searchDate"
        />
      </div>
      <div class="search-list">
        <div class="search-list-item" @click="clickArea">
          <img v-if="areaCheck === null" src="@/assets/img/home/icon-rectangle.png" alt="" />
          <img v-else :src="areaIcon[areaCheck].src" alt="" />
          <p>{{ areaType }}</p>
          <img src="@/assets/img/home/icon-up.png" alt="" />
        </div>
        <div class="search-list-item" @click="kmlInputEl.click()">
          <img src="@/assets/img/home/icon-kml.png" alt="" />
          <input type="file" ref="kmlInputEl" style="display: none" accept=".kml, .KML" @change="uploadKmlFile" />
          <p>导入KML</p>
          <img src="@/assets/img/home/icon-up.png" alt="" />
        </div>
        <div class="search-list-item">
          <img src="@/assets/img/home/icon-location.png" alt="" />
          <el-cascader
            popper-class="drop-down-address"
            v-model="addresssValue"
            :options="addressListData"
            :props="props"
            @change="changeAddress"
            :show-all-levels="false"
            clearable
          />
        </div>
        <!-- <div class="search-list-item" @click="clickTaskType" >
          <img src="@/assets/img/home/icon-select.png" alt="" />
          <p>{{ taskType }}</p>
          <img src="@/assets/img/home/icon-up.png" alt="" />
        </div> -->
        <!-- 区块选择 -->
        <div class="select-area" v-if="areafilterFlag">
          <div
            class="select-area-item"
            :class="{'area-item-acctive': areaCheck === index}"
            v-for="(item, index) in areaArr"
            :key="index"
            @click="clickGrap(index)"
          >
            <img :src="item.src[areaCheck == index ? 1 : 0]" alt="" />
            <p :class="areaCheck == index ? 'area-active' : 'text'">
              {{ item.msg }}
            </p>
          </div>
        </div>
        <!-- 飞行任务类型 -->
        <div class="select-task" v-if="taskFilterFlag">
          <div
            class="select-task-item"
            :class="{'task-item-acctive': taskCheck === index}"
            v-for="(item, index) in taskOptions"
            :key="index"
            @click="clickTask(index)"
          >
            <p :class="taskCheck == index ? 'task-active' : 'text'">
              {{ item.value }}
            </p>
          </div>
        </div>
      </div>
    </div>
    <!-- 右侧数据栏 -->
    <div
      class="sidebar"
      :style="
        mapIndex === 2
          ? ' background: linear-gradient(90deg, rgba(255, 255, 255, 0.4) 0%, #ffffff 100%);'
          : 'background: linear-gradient(90deg, rgba(0,17,55,0.1400) 0%, rgba(0,19,55,0.8600) 59%, #001336 100%);'
      "
      v-show="!tableRightShow"
    >
      <sidebarMsg
        :mapIndex="mapIndex"
        @clickMonth="clickMonth"
        @clickSeason="clickSeason"
        @changeDate="changeDate"
        @changeTaskType="changeTaskType"
      ></sidebarMsg>
    </div>
    <!-- 右侧表格列表 -->
    <div
      ref="rightTableRef"
      class="table-right"
      :style="
        mapIndex === 2
          ? 'background: linear-gradient(90deg, rgba(255,255,255,0.7) 0%, rgba(255,255,255,0.95) 21%, #FFFFFF 100%);'
          : 'background: linear-gradient(90deg, rgba(0,19,55,0.5) 0%, rgba(0,19,54,0.96) 40%, #001336 100%);'
      "
      v-show="tableRightShow"
    >
      <rightTable
        ref="tableRight"
        :mapIndex="mapIndex"
        :tableParams="tableParams"
        @openTable="openTable"
        @closeTableRight="closeTableRight"
        @changeFlightType="changeFlightType"
        @exportTable="exportTable"
        @displayRange="displayRange"
      ></rightTable>
    </div>
    <!-- 海量点弹窗 -->
    <div v-if="drawDialogVisible">
      <drawDialog
        ref="drawDialogRef"
        :drawDialogVisible="drawDialogVisible"
        :mission_id="missionId"
        @closeDialog="closeDrawDialog"
        @clickPostion="clickPostion"
      ></drawDialog>
    </div>
    <!-- 多屏监控 -->
    <multiScreen
      v-if="multiScreenVisible"
      :multiScreenVisible="multiScreenVisible"
      @closeMultiScreen="closeMultiScreen"
    ></multiScreen>
  </div>
</template>
<script lang="ts" setup>
import {ref, onMounted, onUnmounted, getCurrentInstance} from 'vue';
import {ElMessage} from 'element-plus';
import * as turf from '@turf/turf';
import axios from 'axios';
import store from '@/store';
import coordtransform from '@/utils/transform.ts';
import {wgs84togcj02} from '@/views/monitor/fmmapmanager/Tools/transfrom';
import {FmMapManager} from '@/views/monitor/fmmapmanager';
import sidebarMsg from './components/sidebar.vue';
import rightTable from './components/rightTable.vue';
import SwitchMap from '@/utils/switchMap.js';
import censusApi from '@/api/census.ts';
import datetransform from '@/utils/index.ts';
import flyiconHistory from '@/assets/img/home/flyicon_dark.png';
import markerIcon from '@/assets/img/home/dark.svg';
import drawDialog from './components/drawDialog.vue';
import multiScreen from './components/multiScreen.vue';
import {addressList, areaArr, taskOptions, areaIcon} from './address.ts';

const $http = getCurrentInstance()?.appContext.config.globalProperties.$http;

let map: any; // 地图实例
let switchMapManage: any;
const features = ['bg', 'road', 'building', 'point'];
const coordinate = ref('gcj02'); // 采用什么坐标系
const isWgs = ref(false);
let tiandituLayer: {}; // 天地图
let tianditutext: {}; // 天地图文字
let tiandituYinxiangLayer: {}; // 天地图影像
const isFitView = ref(true);
const qhPolygon = ref([]); // 边界线
const qhGcjPolypon = ref([]); // gcj02边界线
const qhWgsPolypon = ref([]); // wgs84边界线
const loading = ref(false);
const switchMapShow = ref(false);
const mapIndex = ref(2);
const historyFlightNum = ref<number>();
const onlineFlightNum = ref<number>();
const drawDialogVisible = ref(false);
const missionId = ref('');
const multiScreenVisible = ref(false);
const timer = ref<any>(null);
let params = {}; // 搜索条件
const date = ref(null);
const areaCheck = ref(null); // 选中的绘制图形
const areafilterFlag = ref(false); // 框选区域下拉
const areaType = ref('框选区域');
const taskCheck = ref(null); // 选择的任务类型
const taskFilterFlag = ref(false); // 任务类型下拉
const taskType = ref('任务类型');
const addressListData = ref([]); // 全国省市区数据
const addresssValue = ref('');
const tableRight = ref();
const rightTableRef = ref();
const tableParams = ref({}); // 右侧表格搜索条件
const tableRightShow = ref(false);
const kmlInputEl = ref(null);
const feimaManager = ref(null);
const monitorDetail = ref(); // 监控详情数据
let routeLine: any; // 飞马航线
let flyArea: any; // 阴影区域
const circleSpot = ref([]); // 圆型区域
const rectangleSpot = ref([]); // 矩形区域
const polygonSpot = ref([]); // 矩形区域
let blockObj; // 区块对象
let lnglatKmlData = []; // 导入的kml数据
let lnglatWgsKmlData = []; // wgs坐标kml数据
let regionPolygon; // 地区搜索边界
let addbounds; // 地区搜索边界坐标集合
let addWgsBounds; // 地区搜索边界wsg坐标集合
// 历史飞行设备
let historyMassMark;
let historyListData = [];
let historyMakerList = [];
// 在线飞行设备
let onlineListData = [];
let onlineMakerList = [];
const props = {
  checkStrictly: true,
};
const drawDialogRef = ref();
const blockTypeList = [2, 3, 4, 8, 99];

/**
 *  初始化地图
 */
let autoComplete; // 行政区查询对象
let geocoder; // 地理编码对象
const initMap = () => {
  map = new AMap.Map('map', {
    resizeEnable: true,
    viewMode: '2D',
    zoom: 6,
    features,
  });
  // 行政区域查询
  autoComplete = new AMap.DistrictSearch({
    extensions: 'all',
    // subdistrict: 1,
    level: 'district',
  });
  // 地理编码
  geocoder = new AMap.Geocoder({
    city: '全国', // 城市设为北京，默认：“全国”
  });
  switchMapManage = new SwitchMap(map);
  // 天地图影像图层
  tiandituYinxiangLayer = new AMap.TileLayer({
    getTileUrl:
      '//t{0,1,2,3,4,5,6,7}.tianditu.gov.cn/DataServer?T=img_w&tk=' +
      import.meta.env.VITE_APP_TIANDITU_KEY +
      '&x=[x]&y=[y]&l=[z]',
    zIndex: 3,
  });
  tiandituLayer = new AMap.TileLayer({
    getTileUrl:
      '//t{0,1,2,3,4,5,6,7}.tianditu.gov.cn/DataServer?T=vec_w&tk=' +
      import.meta.env.VITE_APP_TIANDITU_KEY +
      '&x=[x]&y=[y]&l=[z]',
    zIndex: 3,
  });
  tianditutext = new AMap.TileLayer({
    getTileUrl:
      '//t{0,1,2,3,4,5,6,7}.tianditu.gov.cn/DataServer?T=cva_w&tk=' +
      import.meta.env.VITE_APP_TIANDITU_KEY +
      '&x=[x]&y=[y]&l=[z]',
    zIndex: 101,
  });
  if (isWgs.value) {
    map.setFeatures([]);
    tianditutext.setMap(map);
    tiandituYinxiangLayer.setMap(map);
  }
  mapBorder();
};
/**
 * 打开多屏监视
 */
const openMultiScreen = () => {
  multiScreenVisible.value = !multiScreenVisible.value;
  getOnlineFlight();
};
/**
 * 关闭多屏监视
 */
const closeMultiScreen = () => {
  multiScreenVisible.value = !multiScreenVisible.value;
};
/**
 * 点击切换地图
 */
const openSwitchMap = () => {
  switchMapShow.value = !switchMapShow.value;
};
/**
 * 选择地图
 */
const switchMap = (index) => {
  if (index !== mapIndex.value) {
    mapIndex.value = index;
    switchMapManage
      .switchDifferentMap(index)
      .then((res) => {
        map.clearMap();
        mapBorder();
        if (res) {
          coordinate.value = 'wgs84';
          isWgs.value = true;
          switchSkyMap();
        } else {
          coordinate.value = 'gcj02';
          isWgs.value = false;
          map.setFeatures(features);
          switchGaoDe();
        }
      })
      .catch((err) => {
        throw err;
      });
  }
};
/**
 * 切换成天地图时
 */
const switchSkyMap = () => {
  if (routeLine || flyArea) {
    routeLine.setMap(null);
    flyArea.setMap(null);
    routeLine = new AMap.Polyline({
      ...feimaManager.value.wgs84Airline,
      zIndex: 50,
    });
    // 判断是否是条带航线
    if (blockTypeList.includes(store.state.blockType)) {
      flyArea = new AMap.Polyline({
        path: getFlyArea(monitorDetail.value.data),
        strokeColor: store.state.isOnline ? '#CCC894' : '#95BDCA',
        strokeOpacity: 1,
        strokeWeight: 6,
        // 折线样式还支持 'dashed'
        strokeStyle: 'solid',
        // strokeStyle是dashed时有效
        strokeDasharray: [10, 5],
        lineJoin: 'round',
        lineCap: 'round',
        zIndex: 30,
      });
    } else {
      flyArea = new AMap.Polygon({
        path: getFlyArea(monitorDetail.value.data),
        fillColor: store.state.isOnline ? '#CCC894' : '#95BDCA', // 多边形填充颜色
        borderWeight: 2, // 线条宽度，默认为 1
        strokeColor: store.state.isOnline ? '#e8a443' : '#24DBFF', // 线条颜色
        zIndex: 30,
      });
    }
    // 在线显示区域和航线
    if (!store.state.isOnline) {
      map.add(flyArea);
      map.setFitView(flyArea);
    } else {
      // 非在线只显示区域
      map.add(flyArea);
      routeLine.setMap(map);
      map.setFitView(routeLine);
    }
  }
  if (lnglatWgsKmlData) {
    lnglatWgsKmlData.forEach((path) => {
      drawPolygon(path);
    });
  }
  if (addWgsBounds) {
    drawAddresLine(addWgsBounds);
  }
  if (blockObj) {
    drawRegion();
  }
  drawMarkers(historyMakerList, flyiconHistory);
  drawOnlineMarker(onlineListData);
};
/**
 * 切换到电子地图
 */
const switchGaoDe = () => {
  if (routeLine || flyArea) {
    routeLine.setMap(null);
    flyArea.setMap(null);
    routeLine = new AMap.Polyline({
      ...feimaManager.value.airline,
      zIndex: 50,
    });
    // 判断是否是条带航线
    if (blockTypeList.includes(store.state.blockType)) {
      flyArea = new AMap.Polyline({
        path: getFlyArea(monitorDetail.value.data),
        strokeColor: store.state.isOnline ? '#CCC894' : '#95BDCA',
        strokeOpacity: 1,
        strokeWeight: 6,
        // 折线样式还支持 'dashed'
        strokeStyle: 'solid',
        // strokeStyle是dashed时有效
        strokeDasharray: [10, 5],
        lineJoin: 'round',
        lineCap: 'round',
        zIndex: 30,
      });
    } else {
      flyArea = new AMap.Polygon({
        path: getFlyArea(monitorDetail.value.data),
        fillColor: store.state.isOnline ? '#CCC894' : '#95BDCA', // 多边形填充颜色
        borderWeight: 2, // 线条宽度，默认为 1
        strokeColor: store.state.isOnline ? '#e8a443' : '#24DBFF', // 线条颜色
        zIndex: 30,
      });
    }
    // 在线显示区域和航线
    if (!store.state.isOnline) {
      map.add(flyArea);
      map.setFitView(flyArea);
    } else {
      // 非在线只显示区域
      map.add(flyArea);
      routeLine.setMap(map);
      map.setFitView(routeLine);
    }
  }
  if (lnglatKmlData) {
    lnglatKmlData.forEach((path) => {
      drawPolygon(path);
    });
  }
  if (addbounds) {
    drawAddresLine(addbounds);
  }
  if (blockObj) {
    drawRegion();
  }
  drawMarkers(historyMakerList, flyiconHistory);
  drawOnlineMarker(onlineListData);
};
/**
 * 高亮青海省边界
 */
const mapBorder = () => {
  map.plugin('AMap.DistrictSearch', () => {
    const districtSearch = new AMap.DistrictSearch({
      // 关键字对应的行政区级别，共有5种级别
      level: 'province',
      //  是否显示下级行政区级数，1表示返回下一级行政区
      subdistrict: 0,
      // 返回行政区边界坐标点
      extensions: 'all',
    });
    // 搜索所有省/直辖市信息
    districtSearch.search('青海', (status, result) => {
      // 查询成功时，result即为对应的行政区信息

      qhGcjPolypon.value = result.districtList[0].boundaries;
      qhGcjPolypon.value.forEach((items, index) => {
        qhWgsPolypon.value[index] = [];
        items.forEach((data) => {
          qhWgsPolypon.value[index].push(coordtransform.gcj02towgs84(data.lng, data.lat));
        });
      });

      if (coordinate.value === 'gcj02') {
        handlePolygon(qhGcjPolypon.value);
      } else {
        handlePolygon(qhWgsPolypon.value);
      }
    });
  });
};
/**
 * 绘制边界线
 */
const handlePolygon = (result) => {
  const bounds = result;
  qhPolygon.value = [];
  if (bounds.length) {
    for (let i = 0, l = bounds.length; i < l; i++) {
      // 生成行政区划polygon
      qhPolygon.value.push(
        new AMap.Polygon({
          map, // 指定地图对象
          strokeWeight: 2, // 轮廓线宽度
          path: bounds[i], // 轮廓线的节点坐标数组
          fillOpacity: 0.15, // 透明度
          fillColor: 'transparent', // 填充颜色
          strokeColor: '#dead54', // 线条颜色
        }),
      );
    }
    // 地图自适应
    if (isFitView.value) {
      map.setFitView();
      isFitView.value = false;
    }
  }
};
/**
 * 初始化
 */
const init = () => {
  addressListData.value = datetransform.fixAddressValue(addressList);
  initMap();
  getHistoryFlight();
  getOnlineFlight();
  timerFn();
};
/**
 * 月份
 */
const clickMonth = () => {
  params = {time: 'month'};
  getHistoryFlight();
};
/**
 * 季度
 */
const clickSeason = () => {
  params = {time: 'season'};
  getHistoryFlight();
};
/**
 * 选择时间
 * @param {object} val
 */
const changeDate = (val) => {
  params = val;
  getHistoryFlight();
};
/**
 * 侧边栏选择飞行任务类型
 * @param {sting} type
 */
const changeTaskType = (type) => {
  params.project_type = type;
  getHistoryFlight();
};
/**
 * 时间搜索
 */
const searchDate = () => {
  if (date.value) {
    tableRightShow.value = true;
    date.value = [datetransform.formYYMMDD(date.value[0]), datetransform.formYYMMDD(date.value[1])];
    [params.created_at_from, params.created_at_to] = date.value;
    tableParams.value = params;
  } else {
    delete params.created_at_from;
    delete params.created_at_to;
  }
  getHistoryFlight();
  tableRight.value.getTableDataOffline(params);
};
/**
 * 展开框选区域
 */
const clickArea = () => {
  areafilterFlag.value = !areafilterFlag.value;
  areaCheck.value = null;
};
/**
 * 选择框选图形
 * @param {string} index
 */
let mouseTool;
const clickGrap = (index) => {
  areaCheck.value = index;
  areafilterFlag.value = !areafilterFlag.value;
  if (mouseTool) {
    mouseTool.close();
    mouseTool = null;
  }
  clearParams();
  // 鼠标工具绘制
  mouseTool = new AMap.MouseTool(map);
  switch (areaCheck.value) {
    case 0:
      mouseTool.rectangle({
        strokeColor: '#44FF61',
        strokeOpacity: 1,
        strokeWeight: 3,
        fillColor: '#1CB834',
        fillOpacity: 0.2,
        strokeStyle: 'solid',
      });
      areaType.value = '矩形';
      break;
    case 1:
      mouseTool.circle({
        strokeColor: '#44FF61',
        strokeOpacity: 1,
        strokeWeight: 3,
        fillColor: '#1CB834',
        fillOpacity: 0.2,
        strokeStyle: 'solid',
      });
      areaType.value = '圆形';
      break;
    case 2:
      mouseTool.polygon({
        strokeColor: '#44FF61',
        strokeOpacity: 1,
        strokeWeight: 3,
        fillColor: '#1CB834',
        fillOpacity: 0.2,
        strokeStyle: 'solid',
      });
      areaType.value = '多边形';
      break;
    default:
      break;
  }
  mouseTool.on('draw', (e) => {
    clearParams();
    if (e.obj.CLASS_NAME === 'AMap.Circle') {
      // 圆形
      e.name = '圆形';
      const circleObj = {};
      circleObj.location = [e.obj.De.center.lng, e.obj.De.center.lat];
      circleObj.distance = (Math.round(e.obj.De.radius) / 1000).toFixed(2) + 'km';
      circleObj.radius = e.obj.De.radius;
      params.geo_distance_search = [];
      circleSpot.value.push(circleObj);
      params.geo_distance_search.push(circleObj);
    } else {
      // 多边形
      const spotArr = [];
      e.obj.De.path.forEach((item) => {
        spotArr.push([item.lng, item.lat]);
      });
      // 是否是矩形
      if (e.obj.De.path.length === 4 && e.obj.De.path[0].Q === e.obj.De.path[1].Q) {
        e.name = '矩形';
        params.geo_bounding_search = [];
        rectangleSpot.value.push(getDiagonal(spotArr));
        params.geo_bounding_search.push(getDiagonal(spotArr));
      } else {
        e.name = '多边形';
        const polygonArr = spotArr.concat([spotArr[0]]);
        const poly = turf.polygon([polygonArr]);
        const kinks = turf.kinks(poly);
        if (spotArr.length < 4) {
          ElMessage.warning('多边形的点不得少于4个！');
          mouseTool.close();
          areaCheck.value = null;
          map.remove(e.obj);
          return;
        }
        if (kinks.features.length) {
          ElMessage.warning('多边形的区域不可交叉！');
          mouseTool.close();
          areaCheck.value = null;
          map.remove(e.obj);
          return;
        }
        polygonSpot.value.push(polygonArr);
        params.geo_polygon_search = [];
        params.geo_polygon_search.push(polygonArr);
      }
    }
    blockObj = e;
    mouseTool.close();
    areaCheck.value = null;
    tableRightShow.value = true;
    tableParams.value = params;
    getHistoryFlight();
    tableRight.value.getTableDataOffline(params);
  });
};
/**
 * 绘制框选区域图形
 */
const drawRegion = () => {
  let drawCircle;
  let drawRectangle;
  let drawPolygon;
  let bounds;
  switch (blockObj.name) {
    case '圆形':
      drawCircle = new AMap.Circle({
        center: circleSpot.value[0].location,
        radius: circleSpot.value[0].radius, // 半径
        strokeColor: '#44FF61',
        strokeOpacity: 1,
        strokeWeight: 3,
        fillColor: '#1CB834',
        fillOpacity: 0.2,
        strokeStyle: 'solid',
      });
      map.add(drawCircle);
      break;
    case '矩形':
      bounds = new AMap.Bounds(rectangleSpot.value[0].top_left, rectangleSpot.value[0].bottom_right);
      drawRectangle = new AMap.Rectangle({
        bounds,
        strokeColor: '#44FF61',
        strokeOpacity: 1,
        strokeWeight: 3,
        fillColor: '#1CB834',
        fillOpacity: 0.2,
        strokeStyle: 'solid',
      });

      map.add(drawRectangle);
      break;
    case '多边形':
      drawPolygon = new AMap.Polygon({
        path: polygonSpot.value[0],
        strokeColor: '#44FF61',
        strokeOpacity: 1,
        strokeWeight: 3,
        fillColor: '#1CB834',
        fillOpacity: 0.2,
        strokeStyle: 'solid',
      });
      map.add(drawPolygon);
      break;
    default:
      break;
  }
};
/**
 * 导入KML
 * @param {object} kmlFile
 */
const uploadKmlFile = async (kmlFile) => {
  map.clearMap();
  lnglatKmlData = [];
  lnglatWgsKmlData = [];
  const file = kmlFile.target.files[0];
  // 使用 FileReader 来读取文件
  const reader = new FileReader();
  // 读取纯文本文件,且编码格式为 utf-8
  reader.readAsText(file, 'UTF-8');
  // 读取文件,会触发 onload 异步事件,可使用回调函数 来获取最终的值.
  reader.onload = (e) => {
    const fileContent = e.target.result;
    const data = fileContent.split('<coordinates>');
    data.forEach((item) => {
      if (item.indexOf('</coordinates>') !== -1) {
        const path = [];
        const wgsPath = [];
        const strLnglat = item.split('</coordinates>')[0];
        strLnglat.split(' ').forEach((lnglats) => {
          const lnglat = lnglats.split(',');
          if (lnglat[0] !== '' && lnglat[0]) {
            path.push(coordtransform.wgs84togcj02(lnglat[0], lnglat[1]));
            wgsPath.push(lnglat[0], lnglat[1]);
          }
        });
        if (JSON.stringify(path[0]) !== JSON.stringify(path[path.length - 1])) {
          ElMessage({
            message: '导入的kml区块中含有非多边形，请检查后再导入。',
            type: 'warning',
          });
          return;
        }
        lnglatKmlData.push(path);
        lnglatWgsKmlData.push(wgsPath);
      }
    });

    if (coordinate.value === 'gcj02') {
      lnglatKmlData.forEach((path) => {
        drawPolygon(path);
      });
    } else {
      lnglatWgsKmlData.forEach((path) => {
        drawPolygon(path);
      });
    }

    clearParams();
    params.geo_multi_polygon_search = fixKmlData(lnglatKmlData);
    tableRightShow.value = true;
    tableParams.value = params;
    getHistoryFlight();
    tableRight.value.getTableDataOffline(params);
    map.setFitView();
  };
};
/**
 * 重置导入KML数据格式（传参给后端）
 */
const fixKmlData = (list) => {
  const kmlArr = [];
  list.forEach((item) => {
    if (Array.isArray(item)) {
      const kmlPath = [];
      item.forEach((ite) => {
        kmlPath.push([ite.lng, ite.lat]);
      });
      kmlArr.push(kmlPath);
    }
  });
  return kmlArr;
};
/**
 * 选择地区
 */
let searchAdd = '';
const changeAddress = () => {
  // 清除上一个行政区域
  if (polygons) {
    map.remove(polygons);
    clearParams();
    addbounds = [];
    addWgsBounds = [];
  }
  if (!addresssValue.value) {
    closeTableRight();
    return;
  }
  [params.province, params.city, params.district] = addresssValue.value;
  switch (addresssValue.value.length) {
    case 1:
      searchAdd = params.province;
      break;
    case 2:
      searchAdd = params.city;
      break;
    case 3:
      searchAdd = params.district;
      break;
    default:
      break;
  }

  tableRightShow.value = true;
  tableParams.value = params;
  getHistoryFlight();
  tableRight.value.getTableDataOffline(params);
  // 生成行政区域polygon
  autoComplete.search(searchAdd, (status, result) => {
    addbounds = result.districtList[0].boundaries;
    addWgsBounds = [];
    addbounds.forEach((items, index) => {
      addWgsBounds[index] = [];
      items.forEach((data) => {
        addWgsBounds[index].push(coordtransform.gcj02towgs84(data.lng, data.lat));
      });
    });
    if (coordinate.value === 'gcj02') {
      drawAddresLine(addbounds);
    } else {
      drawAddresLine(addWgsBounds);
    }
  });
};
/**
 * 绘制区域搜索边界线
 * @param {arrary} addLineList
 */
let polygons;
const drawAddresLine = (addLineList) => {
  const bounds = addLineList;
  polygons = [];
  if (bounds) {
    for (let i = 0, l = bounds.length; i < l; i++) {
      regionPolygon = new AMap.Polygon({
        map,
        strokeWeight: 2,
        path: bounds[i],
        fillOpacity: 0.5,
        fillColor: '#DCDCDC',
        strokeColor: '#FF00E0',
      });
      polygons.push(regionPolygon);
    }
  }
  // 设置区域中心点并缩放级别
  geocoder.getLocation(searchAdd, (status, result) => {
    if (status === 'complete' && result.geocodes.length) {
      map.setZoomAndCenter(9, [result.geocodes[0].location.lng, result.geocodes[0].location.lat]);
    } else {
      ElMessage.warning('根据地址查询位置失败');
    }
  });
};
/**
 * 点击飞行任务类型
 */
const clickTaskType = () => {
  taskFilterFlag.value = !taskFilterFlag.value;
  taskCheck.value = null;
};
/**
 * 选择任务类型
 * @param {string} index
 */
const clickTask = (index) => {
  taskCheck.value = index;
};
/**
 * 展开/收起表格侧边栏
 */
const openTable = (flag) => {
  if (!flag) {
    rightTableRef.value.style.width = '740px';
  } else {
    rightTableRef.value.style.width = '1260px';
  }
};
/**
 * 关闭表格侧边栏
 */
const closeTableRight = () => {
  tableRightShow.value = false;
  addresssValue.value = '';
  params = {};
  areaType.value = '框选区域';
  map.clearMap();
  date.value = null;
  drawDialogVisible.value = false;
  getHistoryFlight();
  map.setFitView();
};
/**
 *  选择飞行状态
 * @param {string} flightType
 */
const changeFlightType = (flightType) => {
  if (flightType === '在线飞行') {
    tableRight.value.getTableDataOnline(params);
  } else {
    tableRight.value.getTableDataOffline(params);
  }
};
/**
 * 导出/导出全部
 * @param {sting} type
 * @param {array} arr
 */
const exportTable = (type, arr) => {
  if (type === 'single') {
    censusApi
      .exportKml({mission_id_list: arr})
      .then((res) => {
        if (res.status === 0) {
          window.open(res.data);
          ElMessage.success(res.message);
        }
      })
      .catch((err) => {});
  } else {
    censusApi
      .exportKml(params)
      .then((res) => {
        if (res.status === 0) {
          window.open(res.data);
          ElMessage.success(res.message);
        }
      })
      .catch((err) => {});
  }
};
/**
 * 显示范围
 * @param {object} row
 */
const displayRange = async (row) => {
  if (flyArea || routeLine) {
    map.remove(flyArea);
    map.remove(routeLine);
  }
  drawDialogVisible.value = true;
  missionId.value = row.mission_id;
  store.commit('setFlightState', row.isOnline);
  store.commit('setFlightBlockType', row.feima_block_type);
  await getMonitorDetail();
  initFlightData(monitorDetail.value, row.isOnline);
};
/**
 * 点击点标记图标
 */
const clickMaker = async (e) => {
  if (flyArea || routeLine) {
    map.remove(flyArea);
    map.remove(routeLine);
  }
  let target;

  if (e.data) {
    target = e.data;
  } else {
    target = e.target.getExtData();
  }
  missionId.value = target.mission_id;
  store.commit('setFlightState', e.target.De.isOnline);
  store.commit('setFlightBlockType', target.feima_block_type);
  if (drawDialogVisible.value) {
    drawDialogRef.value.getDetailData(missionId.value);
  }
  await getMonitorDetail();
  drawDialogVisible.value = true;
  initFlightData(monitorDetail.value, e.target.De.isOnline);
};
/**
 * 关闭点标记弹窗
 */
const closeDrawDialog = () => {
  drawDialogVisible.value = false;
};
/**
 * 定位
 * @param {array} lnglat
 */
let marker;
const clickPostion = (lnglat) => {
  if (marker) {
    marker.setMap(null);
    marker = null;
  }
  marker = new AMap.Marker({
    icon: new AMap.Icon({
      size: new AMap.Size(40, 40), // 图标大小
    }),
  });
  map.add(marker); // 显示图标
  marker.setPosition(lnglat);
  map.setZoomAndCenter(15, lnglat);
  closeDrawDialog();
};
/**
 *  绘制海量点
 * @param {any} maskData
 * @param {string} imgUrl
 */
const drawMarkers = (maskData: any, imgUrl: String) => {
  const makerList = maskData.map((item) => {
    if (isWgs.value) {
      item.lnglat = coordtransform.gcj02towgs84(item.lnglat[0], item.lnglat[1]);
    } else {
      item.lnglat = item.lnglat.splice(0, 2);
    }
    return {
      lnglat: item.lnglat,
      mission_id: item.mission_id,
      serial_no: item.serial_no,
      brand_name: item.brand_name,
      feima_block_type: item.feima_block_type,
    };
  });
  const massMask = new AMap.MassMarks(makerList, {
    zooms: [3, 19],
    zIndex: 111,
    style: {
      anchor: new AMap.Pixel(6, 6),
      url: imgUrl,
      size: new AMap.Size(22, 22),
    },
    isOnline: false,
  });
  massMask.on('click', (e) => {
    clickMaker(e);
  });
  massMask.setData(makerList);
  map.add(massMask);
  return massMask;
};

/**
 * 历史飞行设备
 */
let pageSize = 1;
let ListTotal = 2;
const getHistoryFlight = async () => {
  loading.value = true;
  params.page = pageSize;
  const res = await censusApi.getFlightData(params);
  clearHistoryMaker();
  if (res.status === 0) {
    historyListData = res.data.data;
    ListTotal = Math.ceil(res.data.total / res.data.per_page);
    historyFlightNum.value = res.data.total;
    await callBackHistory();
    pageSize = 1;
    historyListData.forEach((item) => {
      const lnglat = [Number(item.point.lon), Number(item.point.lat)];
      historyMakerList.push({
        mission_id: item.mission_id,
        serial_no: item.serial_no,
        brand_name: item.brand_name,
        feima_block_type: item.feima_block_type,
        lnglat,
      });
    });
    historyMassMark = drawMarkers(historyMakerList, flyiconHistory);
  }
  loading.value = false;
};

/**
 * 回调历史架次请求
 */
const callBackHistory = async () => {
  for (let i = 2; i <= ListTotal; i++) {
    pageSize = i;
    params.page = pageSize;
    // eslint-disable-next-line no-await-in-loop, no-loop-func
    await $http.get('/api/deviceView/sortiesList', {...params}).then((res: any) => {
      if (res.data.data) {
        historyListData = historyListData.concat(res.data.data);
      }
    });
  }
};

/**
 * 在线飞行设备
 */
const getOnlineFlight = async () => {
  const data = await censusApi.onloneDevice();
  clearOnlineMaker();
  if (data.status === 0) {
    onlineListData = data.data;
    onlineFlightNum.value = data.data.length;
    drawOnlineMarker(onlineListData);
  }
};
/**
 * 绘制在线设备点标记
 * @param {array} onlinList
 */
const drawOnlineMarker = (onlinList) => {
  onlinList.forEach((item) => {
    let lnglat;
    if (isWgs.value) {
      lnglat = coordtransform.gcj02towgs84(item.lon, item.lat);
    } else {
      lnglat = [item.lon, item.lat];
    }
    const markers = new AMap.Marker({
      position: lnglat,
      icon: new AMap.Icon({
        size: new AMap.Size(32, 58),
        imageSize: new AMap.Size(32, 58),
        image: markerIcon,
      }),
      offset: new AMap.Pixel(-29, -29),
      zIndex: 122,
      isOnline: true,
    });
    markers.setExtData({
      mission_id: item.mission_id,
      serial_no: item.serial_no,
      feima_block_type: item.feima_block_type,
    });
    markers.on('click', (e) => {
      clickMaker(e);
    });

    onlineMakerList.push(markers);
    map.add(markers);
  });
};
/**
 * 获取监控详情数据
 */
const getMonitorDetail = async () => {
  const exportUrl = `${import.meta.env.VITE_MONITOR_URL}/flightMission/monitor`;
  const data = await axios({
    method: 'get',
    url: exportUrl,
    headers: {
      token: localStorage.getItem('token'),
    },
    params: {
      local_id: missionId.value,
    },
  });
  monitorDetail.value = data.data.data;
};
/**
 * 获取websocket Url
 */
const getPlaneWebsocketUrl = () =>
  new Promise((resolve, reject) => {
    $http
      .get('//airport.afuav.com/api/device/monitor/info', {
        serial_no: monitorDetail.value.data.uas_serial_id,
      })
      .then((response) => {
        resolve(response.data);
      })
      .catch((error) => {
        reject(error);
      });
  });
/**
 * 获取阴影区域数据
 * @param {array} areaData
 */
const getFlyArea = (areaData) => {
  const areaList = [];
  let posi = [];
  areaData.survey_area_coordinate_points.split(';').forEach((item) => {
    if (item) {
      const [lat, lng] = item.split(',');
      posi = wgs84togcj02(lng, lat);
      if (isWgs.value) {
        areaList.push([lng, lat]);
      } else if (areaData.plane_type === 'Phantom 4 Pro') {
        areaList.push([lng, lat]);
      } else {
        areaList.push([posi.longitude, posi.latitude]);
      }
    }
  });
  return areaList;
};
/**
 * 初始化飞行数据
 * @param {object} data
 */
const initFlightData = async (data) => {
  let wsUrl = '';
  let tbId = '';
  await getPlaneWebsocketUrl().then((res) => {
    wsUrl = res.ws_url;
    tbId = res.data.tb_id;
  });
  const fmMonitorOptions = {
    flight_data: data.data, // 必填。 请求到的任务数据
    local_id: data.data.local_id, // 必填。任务id
    url: wsUrl, // 必填。websocket监听地址
    platform: '', // 选填。不填默认web端
    isWgsNeeded: false, // 选填。不填默认false， 即 不生成wgs航线/标记点
    /*
     * airlineOptions 航线配置
     * base_airline_options: 底层航线，upper_airline_options： 上层航线
     * 具体航线配置参考Polyline文档
     */
    airlineOptions: {
      base_airline_options: {
        // 选填。底层航线
        strokeColor: '#DEA52B',
        strokeWidth: 4,
        id: '1',
      },
    },
    /*
     * markersOptions 标记点配置
     * landingMarker: 起飞点，endPointMarker: 终止点，planeMarker:飞机；
     * 网页端参考amap marker文档, uniapp端参考文档。配置除图片和位置外的所需参数
     */
    markersOptions: {
      landingMarker: {}, // 起飞点
      endPointMarker: {}, // 终止点
      planeMarker: {}, // 飞机
    },
  };

  fmMonitorOptions.wsMessageFunc = () =>
    `{"attrSubCmds":[],"tsSubCmds":[{"entityType":"DEVICE","entityId":"${tbId}","scope":"LATEST_TELEMETRY","cmdId":1}],"historyCmds":[]}`;

  feimaManager.value = new FmMapManager(fmMonitorOptions);
  feimaManager.value.createMonitor();
  // 判断是否是条带航线
  if (blockTypeList.includes(store.state.blockType)) {
    flyArea = new AMap.Polyline({
      path: getFlyArea(data.data),
      strokeColor: store.state.isOnline ? '#e8a443' : '#24DBFF',
      strokeOpacity: 1,
      strokeWeight: 6,
      // 折线样式还支持 'dashed'
      strokeStyle: 'solid',
      // strokeStyle是dashed时有效
      strokeDasharray: [10, 5],
      lineJoin: 'round',
      lineCap: 'round',
      zIndex: 30,
    });
  } else {
    flyArea = new AMap.Polygon({
      path: getFlyArea(data.data),
      fillColor: store.state.isOnline ? '#CCC894' : '#95BDCA', // 多边形填充颜色
      borderWeight: 2, // 线条宽度，默认为 1
      strokeColor: store.state.isOnline ? '#e8a443' : '#24DBFF', // 线条颜色
      zIndex: 30,
    });
  }

  if (isWgs.value) {
    routeLine = new AMap.Polyline({
      ...feimaManager.value.wgs84Airline,
      zIndex: 50,
    });
  } else {
    routeLine = new AMap.Polyline({
      ...feimaManager.value.airline,
      zIndex: 50,
    });
  }
  // 在线显示区域和航线
  if (!store.state.isOnline) {
    map.add(flyArea);
    map.setFitView(flyArea);
  } else {
    // 非在线只显示区域
    map.add(flyArea);
    routeLine.setMap(map);
    map.setFitView(routeLine);
  }
  // 设置飞机
  // websocket端口
  feimaManager.value.errorMonitor = (error) => {
    this.$message('连接已断开，请重新进入');
  };
  loading.value = false;
};
/**
 * 清除历史海量点
 */
const clearHistoryMaker = () => {
  if (historyMassMark) {
    historyListData = [];
    historyMakerList = [];
    historyMassMark.clear();
  }
};
/**
 * 清除在线标记点
 */
const clearOnlineMaker = () => {
  if (onlineMakerList.length) {
    map.remove(onlineMakerList);
    onlineListData = [];
    onlineMakerList = [];
  }
};
/**
 * 清除其他搜索条件
 */
const clearParams = () => {
  delete params.geo_multi_polygon_search;
  delete params.geo_bounding_search;
  delete params.geo_distance_search;
  delete params.geo_polygon_search;
  delete params.province;
  delete params.city;
  delete params.district;
  if (blockObj) {
    blockObj.obj.setMap(null);
    blockObj = null;
    circleSpot.value = [];
    polygonSpot.value = [];
    rectangleSpot.value = [];
  }
};
/**
 * 定时器
 */
const timerFn = () => {
  timer.value = setInterval(() => {
    getOnlineFlight();
  }, 15000);
};

/**
 * 绘制多边形
 * @param {Array} path
 */
const drawPolygon = (path) => {
  const polygon = new AMap.Polygon({
    path,
    strokeColor: '#FF5200 ',
    strokeOpacity: 1,
    strokeWeight: 3,
    fillColor: '#B8411C',
    fillOpacity: 0.2,
    strokeStyle: 'solid',
  });
  map.add(polygon);
  return polygon;
};
/**
 * 获取矩形的对角坐标
 * @param {arr}
 */
const getDiagonal = (arr) => {
  const obj = {};
  const lng = [];
  const lat = [];
  arr.forEach((item) => {
    lng.push(item[0]);
    lat.push(item[1]);
  });
  lng.sort((a, b) => a - b);
  lat.sort((a, b) => a - b);
  obj.top_left = [lng[0], lat[3]];
  obj.bottom_right = [lng[3], lat[0]];
  return obj;
};

onMounted(() => {
  init();
});

onUnmounted(() => {
  clearInterval(timer.value);
  timer.value = null;
});
</script>
<style lang="scss" scoped>
@import './index.scss';
</style>
<style lang="scss">
.drop-down-date {
  position: absolute;
  top: 682px !important;
  left: 35px !important;
  z-index: 9999 !important;
  .el-date-range-picker .el-picker-panel__content {
    background: rgba(14, 24, 52, 0.8);
    color: #fff;
  }
  .el-date-table td.next-month,
  .el-date-table td.prev-month {
    color: #999999;
  }
  .el-date-table td .available {
    color: #fff;
  }
  .el-date-table td .available .in-range {
    color: #999999 !important;
  }
  .el-date-range-picker__header {
    color: #fff;
  }
  .el-picker-panel__icon-btn .el-icon {
    color: #fff;
  }
  .el-date-table th {
    color: #fff;
  }
  .el-date-table td.in-range .el-date-table-cell {
    background: rgba(85, 210, 255, 0.3);
  }
  .el-date-table td.start-date .el-date-table-cell {
    border-radius: 0;
  }
  .el-date-table td .el-date-table-cell .el-date-table-cell__text {
    border-radius: 0;
  }
  .el-date-table td.end-date .el-date-table-cell {
    border-radius: 0;
  }
  .el-date-table td.today .el-date-table-cell__text {
    border: 1px solid #1890ff;
  }
}
.drop-down-address {
  position: absolute;
  left: 610px !important;
  z-index: 9999 !important;
  .el-cascader-menu__wrap.el-scrollbar__wrap {
    background: rgba(14, 24, 52, 0.8);
  }
  .el-cascader-node {
    color: #fff;
  }
  .el-cascader-node:not(.is-disabled):focus,
  .el-cascader-node:not(.is-disabled):hover {
    background: rgba(179, 209, 242, 0.15);
  }
  .el-cascader-menu {
    border-right: 0;
    margin-right: 2px;
  }
  .el-cascader-node.is-selectable.in-active-path {
    color: #1890ff;
  }
}
</style>
